package com.jwater.core.manager.job.timer;

import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jwater.org.quartz.CronScheduleBuilder;
import jwater.org.quartz.CronTrigger;
import jwater.org.quartz.JobBuilder;
import jwater.org.quartz.JobDetail;
import jwater.org.quartz.JobKey;
import jwater.org.quartz.Scheduler;
import jwater.org.quartz.SchedulerFactory;
import jwater.org.quartz.TriggerBuilder;
import jwater.org.quartz.impl.StdSchedulerFactory;

/**
 * @description:
 * @author: jnner
 * @createDate: 2021/2/5
 * @version: 1.0
 */
public class CronTimer {
    protected static Logger logger = LoggerFactory.getLogger(CronTimer.class);

    private static SchedulerFactory sf = new StdSchedulerFactory();
    private volatile static Scheduler scheduledWithCron;

    private JobKey jobKey;
    protected TimerTask task;
    private String name;
    private String cron;
    protected boolean isRunning = true;

    static {
        try {
            synchronized (sf) {
                if (scheduledWithCron == null) {
                    scheduledWithCron = sf.getScheduler();
                    scheduledWithCron.start();
                }
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    public CronTimer(TimerTask task, String cron) {
        this.task = task;
        this.name = UUID.randomUUID().toString();
        this.cron = cron;
    }

    public CronTimer(TimerTask task, String name, String cron) {
        this.task = task;
        this.name = name;
        this.cron = cron;
    }

    protected JobKey newCronJob(String name, String cron) {
        try {
            JobDetail job = JobBuilder.newJob(CronJob.class).withIdentity(name + "Job", name + "Group").build();
            job.getJobDataMap().put("CronTimer", this);
            CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
                    .withIdentity(name + "Trigger", name + "Group").withSchedule(CronScheduleBuilder.cronSchedule(cron))
                    .build();
            scheduledWithCron.scheduleJob(job, trigger);
            return job.getKey();
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return null;
    }

    public void start() {
        isRunning = true;
        jobKey = newCronJob(name, cron);
    }

    public void stop() {
        try {
            isRunning = false;
            if (jobKey != null) {
                scheduledWithCron.deleteJob(jobKey);
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }
}
